Amazon Redshift: マテリアライズド・ビュー(Materialized View)のリフレッシュ(REFRESH)について
下記エントリでは、一般利用が可能となったAmazon Redshiftの「マテリアライズド・ビュー(Materialized View)」の作成についてご紹介しました。
当エントリでは、作成したマテリアライズド・ビュー(Materialized View)に対するリフレッシュ(REFRESH)の概要と挙動について見ていきたいと思います。
構文
マテリアライズド・ビューの更新は至ってシンプル。下記構文の形で対象となるビュー名を指定・実行するだけです。
マテリアライズド・ビュー 2つの更新タイプ
REFRESH MATERIALIZED VIEWを実行すると、Amazon Redshiftは対象に含まれるベーステーブルで行われた変更を識別し、それらの変更をマテリアライズド・ビューに反映します。
「マテリアライズド・ビュー」では、「増分リフレッシュ(incremental refresh)」と「フルリフレッシュ(full refresh)」の2つのデータ更新方法を取りうる事が可能です。これについてはビュー作成時に選べるものでは無く、作成時のクエリの状況に拠ってAmazon Redshift側で判定・対応が行われます。「増分リフレッシュ(incremental refresh)」で作成されたマテリアライズド・ビューの場合差分のみを検知、反映する形となり、これが叶わない(増分リフレッシュが実行出来ない)クエリと判断されたマテリアライズド・ビューと判断されたものは「フルリフレッシュ」でマテリアライズド・ビューのすべてのデータ交換、基盤となるSQL文を再実行します。
増分更新をサポートするマテリアライズド・ビューとなるか否かについては、以下に挙げるSQL要素のいずれかを利用しているか否かに影響を受けます。下記のものをビュー作成時のクエリに利用している場合、リフレッシュの方式は「フルリフレッシュ」で行う形となります。
- 外部結合:RIGHT OUTER JOIN, LEFT OUTER JOIN, FULL OUTER JOIN
- 集合演算:UNION、INTERSECT、EXCEPT、MINUS)
- 集計関数:AVG、MEDIAN、PERCENTILE_CONT、MAX、MIN、LISTAGG、STDDEV_SAMP、STDDEV_POP、APPROXIMATE COUNT、APPROXIMATE PERCENTILE、およびビット単位の集約関数
- COUNTとSUMについてはサポート対象に含まれます。
- DISTINCT COUNT、DISTINCT SUM等のDISTINCT集計関数
- ウィンドウ関数
- システム管理系の関数
- システム情報系の関数
- リーダーノードのみで利用可能な関数:CURRENT_SCHEMA, CURRENT_SCHEMAS, HAS_DATABASE_PRIVILEGE, HAS_SCHEMA_PRIVILEGE, HAS_TABLE_PRIVILEGE, AGE, CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME, NOW
- 日付関数:CURRENT_DATE, DATE, DATE_PART, DATE_TRUNC, DATE_CMP_TIMESTAMPTZ, SYSDATE, TIMEOFDAY, TO_TIMESTAMP
- 数学関数:RANDOM
- 日付型のフォーマット関数:TO_CHAR WITH TIMESTAMPTZ
- クエリの最適化に一時テーブルを使用するクエリ
- FROM句以外の場所で用いられるサブクエリ
また、REFRESH MATERIALIZED VIEWの利用に関する諸注意ポイントとしては以下のものが挙げられます。
- REFRESH MATERIALIZED VIEWを実行出来るのは所有者のみ、また対象ベーステーブルに於けるSELECT権限を所有している事が条件
- REFRESH MATERIALIZED VIEWは独自のトランザクションとして実行。リフレッシュ対象のデータに含まれるか否かについては、Amazon Redshiftトランザクションセマンティクスに従う形となる
- 「増分リフレッシュ」タイプのマテリアライズド・ビューの場合、REFRESH MATERIALIZED VIEWは既にコミットされているベーステーブルのデータ行が対象となることに注意。同一トランザクションでのデータ更新の後にREFRESH MATERIALIZED VIEWを実行してもその内容は反映されない
- 「フルリフレッシュ」タイプのマテリアライズド・ビューの場合、更新トランザクションに表示されるすべてのベーステーブル行が表示される
マテリアライズド・ビュー更新(REFRESH MATERIALIZED VIEW):実践
では、実際にREFRESH MATERIALIZED VIEWコマンドの挙動を試してみましょう。下記の形で、とてもシンプルなテーブルを用意。データも数件投入しておきます。
# CREATE TABLE public.mtviewtest ( user_id INT NOT NULL, user_name VARCHAR(10) NOT NULL ); CREATE TABLE # INSERT INTO public.mtviewtest VALUES (1,'AAAAA'); # INSERT INTO public.mtviewtest VALUES (2,'BBBBB'); # INSERT INTO public.mtviewtest VALUES (3,'CCCCC');
マテリアライズド・ビューを作成。この場合「増分リフレッシュが行えないマテリアライズド・ビュー作成」の制限には引っ掛かっていない状態です。
# CREATE MATERIALIZED VIEW public.mtview AS SELECT * FROM public.mtviewtest; CREATE MATERIALIZED VIEW
ですが、マテビュー作成後に投入したデータは、そのままではマテビューには反映されていません。マテビューに対してSELECTを実行しても、返ってくるのはマテビュー作成前に投入した3件のみです。
# INSERT INTO public.mtviewtest VALUES (4,'DDDDD'); # INSERT INTO public.mtviewtest VALUES (5,'EEEEE'); # SELECT * FROM public.mtview ORDER BY user_id; user_id | user_name ---------+----------- 1 | AAAAA 2 | BBBBB 3 | CCCCC (3 rows)
REFRESH MATERIALIZED VIEW実行。増分更新が成功した旨メッセージが表示され、SELECT文の結果も増分が反映された形となりました。
# REFRESH MATERIALIZED VIEW public.mtview; INFO: Materialized view mtview was incrementally updated successfully. REFRESH # SELECT * FROM public.mtview; user_id | user_name ---------+----------- 1 | AAAAA 2 | BBBBB 3 | CCCCC 4 | DDDDD 5 | EEEEE (5 rows)
次いで、上記作成テーブルと同じ定義の別名テーブルを用意。こちらにもデータを入れておきます。
# CREATE TABLE public.mtviewtest2 ( user_id INT NOT NULL, user_name VARCHAR(10) NOT NULL ); CREATE TABLE # INSERT INTO public.mtviewtest2 VALUES (100,'XXXXX'); # INSERT INTO public.mtviewtest2 VALUES (101,'YYYYY'); # INSERT INTO public.mtviewtest2 VALUES (102,'ZZZZZ');
別途CREATE MATERIALIZED VIEW実行。ただこちらのクエリには、増分リフレッシュが行えない条件(UNION)を敢えて含めてみています。マテビューの作成は行えましたが、増分リフレッシュが行えない旨のメッセージも表示されていました。
# CREATE MATERIALIZED VIEW public.mtview2 AS ( SELECT * FROM public.mtviewtest UNION ALL SELECT * FROM public.mtviewtest2 ); WARNING: An incrementally maintained materialized view could not be created, reason: Set operations are not supported. The materialized view created, public.mtview2, will be recomputed from scratch for every REFRESH. CREATE MATERIALIZED VIEW
データ追記→REFRESH MATERIALIZED VIEW→リフレッシュ反映を確認。REFRESH MATERIALIZED VIEWコマンド実行後のメッセージが増分リフレッシュ時のものとは異なっている事が確認出来ました。
cmawsteamdb=# REFRESH MATERIALIZED VIEW public.mtview2; INFO: Materialized view mtview2 is already up to date. REFRESH cmawsteamdb=# INSERT INTO public.mtviewtest2 VALUES (103,'QQQQQ'); cmawsteamdb=# INSERT INTO public.mtviewtest2 VALUES (104,'RRRRR'); cmawsteamdb=# REFRESH MATERIALIZED VIEW public.mtview2; INFO: Materialized view mtview2 was recomputed successfully. REFRESH # SELECT * FROM public.mtview2 ORDER BY user_id; user_id | user_name ---------+----------- 1 | AAAAA 2 | BBBBB 3 | CCCCC 4 | DDDDD 5 | EEEEE 100 | XXXXX 101 | YYYYY 102 | ZZZZZ 103 | QQQQQ 104 | RRRRR (10 rows)
まとめ
という訳で、Amazon Redshiftの新機能「マテリアライズド・ビュー(Materialized View)」のリフレッシュ(REFRESH MATERIALIZED VIEW)に関する内容の紹介でした。増分リフレッシュとフルリフレッシュの違い、またトランザクション絡みの挙動については内容を正しく把握した上で使って行きたいところですね。